module sdram_data_test1(
			 sclk,
			 resetb,
			 
			 test_start,
			 test_end,
			 
			 sdram_cnt,
			 sdram_addr,
			 sdram_bank,
			 sdram_oeb,
			 
			 w_data,
			 r_data,
			 
			 unmatch,
			 work_on
			);
			
parameter	Sdram_A_Width=13;
parameter	Sdram_D_Width=32;
parameter	Sdram_C_Width=4;
parameter	Input_delay=1;
parameter	Output_delay=1;	
parameter	Optional_time=4;
parameter	Base_length=8+Input_delay+Output_delay+Optional_time;
parameter	Cycle_write=Sdram_D_Width;
parameter	Cycle_length=(Sdram_D_Width+1)*2-1;	


parameter	Mode_Reg_Set	=5'b00000;			//0
parameter	Auto_Refresh	=5'b00010;			//2
parameter	Row_Active	=5'b00110;			//6
parameter	Pre_Charge	=5'b00100;			//4
parameter	PreCharge_All	=5'b00101;			//5
parameter	Write		=5'b01000;			//8
parameter	Write_Pre	=5'b01001;			//9
parameter	Read		=5'b01010;			//10
parameter	Read_Pre	=5'b01011;			//11
parameter	Nop		=5'b01110;			//14
parameter	Dsel		=5'b11110;			//30		
			 
input		sclk;
input		resetb;

input		test_start;

output		test_end;
output		unmatch;
output		work_on;


output	[4:0]	sdram_cnt;
output	[10:0]	sdram_addr;
output	[1:0]	sdram_bank;
output		sdram_oeb;
output	[31:0]	w_data;
input	[31:0]	r_data;

wire		sclk;
wire		resetb;

wire		test_start;

reg		test_end;
reg		unmatch;
reg		work_on;

wire	[4:0]	sdram_cnt;
reg	[10:0]	sdram_addr;
wire	[1:0]	sdram_bank;
reg		sdram_oeb;
reg	[31:0]	w_data;
wire	[31:0]	r_data;


reg		work_on_last;
reg		cycle_read;
reg	[6:0]	base_count;
reg	[6:0]	cycle_count;
reg	[4:0]	command;
reg	[31:0]	data_in;
reg		base_end;
reg		cycle_end;
reg		flag_comp1,flag_comp2,unmatch_tmp1,unmatch_tmp2;
wire		unmatch_tmp;
reg		flag;
reg		test_start_last;	



always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		test_start_last<=0;
	else 	
		test_start_last<=test_start;
	
always	@(posedge sclk or negedge resetb)	
	if (resetb==0)
		test_end<=0;
	else if (work_on==0 && work_on_last==1)
		test_end<=1;
	else
		test_end<=0;	
				
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		work_on<=0;
	else if (test_start==0 && test_start_last==1)
		work_on<=1;
	else if (base_end==1 && cycle_end==1)
		work_on<=0;

always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		work_on_last<=0;
	else	
		work_on_last<=work_on;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		base_count<=0;
	else if (work_on==0 || base_end==1)
		base_count<=0;
	else
		base_count<=base_count+1;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		base_end<=0;
	else if(base_count==Base_length)
		base_end<=1;
	else
		base_end<=0;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		cycle_count<=0;
	else if (work_on==0)
		cycle_count<=0;
	else if (base_end==1)
		cycle_count<=cycle_count+1;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		cycle_read<=0;
	else if (cycle_count==Cycle_write)
		cycle_read<=1;
	else
		cycle_read<=0;				
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		cycle_end<=0;
	else if (cycle_count==Cycle_length)
		cycle_end<=1;
	else
		cycle_end<=0;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		flag<=0;
	else if (base_end==1 && cycle_read==1)
		flag<=1;
	else if (work_on==0)
		flag<=0;				

always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		data_in<=1;
	else if (base_end==1 && cycle_read==1)
		data_in<=1;
	else if (base_end==1 && cycle_end==1)
		data_in<=1;	
	else if (base_end==1)
		data_in<={data_in[Sdram_D_Width-2:0],1'b0};	
		
assign	sdram_cnt[4]=1;
assign	sdram_cnt[3:0]=command[4:1];
assign	sdram_bank=0;

always @(posedge sclk or negedge resetb)
	if (resetb==0)
		command<=Nop;
	else if (cycle_count<Sdram_D_Width+1)
		case (base_count)
			7'h02:		command<=Row_Active;
			7'h05:		command<=Write;
			7'h08:		command<=Pre_Charge;
			default:	command<=Nop;
		endcase
	else 
		case (base_count)
			7'h02:		command<=Row_Active;
			7'h05:		command<=Read;
			7'h08:		command<=Pre_Charge;
			default:	command<=Nop;
		endcase	
														
//always	@(posedge sclk)
//	w_data<=data_in;
	
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		w_data<=0;
	else
		case(base_count)
			7'h05:		w_data<=data_in;
			default:	w_data<=0;
		endcase
	
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		sdram_addr<=0;
	else if (flag==1)
		sdram_addr<=cycle_count-33;
	else
		sdram_addr<=cycle_count;		
			
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		sdram_oeb<=0;
	else if (cycle_count<33)
		sdram_oeb<=1;
	else
		sdram_oeb<=0;
		
	
	
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		flag_comp1<=0;
	else if (cycle_read==1 && base_end==1)
		flag_comp1<=1;
	else if (work_on==0)
		flag_comp1<=0;
		
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		flag_comp2<=0;
	else if (base_count==(8+Input_delay+Output_delay+1))
		flag_comp2<=1;
	else
		flag_comp2<=0;
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		unmatch_tmp1<=0;
	else if (r_data[15:0]==data_in[15:0])
		unmatch_tmp1<=0;
	else 
		unmatch_tmp1<=1;	
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		unmatch_tmp2<=0;
	else if (r_data[31:16]==data_in[31:16])
		unmatch_tmp2<=0;
	else 
		unmatch_tmp2<=1;
		
assign	unmatch_tmp=unmatch_tmp1 | unmatch_tmp2;		
															
					
always	@(posedge sclk or negedge resetb)
	if (resetb==0)
		unmatch<=0;
	else if (flag_comp1==1 && flag_comp2==1)
		unmatch<=unmatch_tmp;
	else
		unmatch<=0;		
														
											
endmodule				
		
				
						
	


			 